package com.weilele.mvvm.view

import android.content.Context
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.Scroller
import com.weilele.mvvm.widget.BaseFrameLayout
import com.weilele.mvvm.widget.BaseLinearLayout
import kotlin.math.abs


/**
 * 当子view 不能再向下滑动的时候
 * 整个视图开始向下滑动
 * 可以做下滑隐藏对话框
 * 可以扩展上拉刷新下拉加载的view
 */
class ScrollPager2View : BaseLinearLayout, GestureDetector.OnGestureListener {
    private val viewConfiguration by lazy { ViewConfiguration.get(context) }
    private val flingVelocityOld by lazy { viewConfiguration.scaledMinimumFlingVelocity }
    private val flingVelocity = 2000f
    private val scroller by lazy { Scroller(context) }
    private val gestureDetector by lazy { GestureDetector(context, this) }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
    )


    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                checkScrollStatus()
            }
            else -> {
            }
        }
        return gestureDetector.onTouchEvent(event)
    }

    /**
     * 检查是滑动到最大处还是原始状态
     */
    private fun checkScrollStatus() {
        val scrollX = this.scrollX
        val scrollY = this.scrollY
        val width = this.width
        val height = this.height
        val widthHalf = width / 2
        val heightHalf = height / 2
        val finalX = when {
            scrollX > widthHalf -> {
                width
            }
            scrollX < -widthHalf -> {
                -width
            }
            else -> {
                0
            }
        }
        val finalY = when {
            scrollY > heightHalf -> {
                width
            }
            scrollY < -heightHalf -> {
                -width
            }
            else -> {
                0
            }
        }
        scroller.startScroll(scrollX, scrollY, finalX - scrollX, 0)
        invalidate()
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return super.onInterceptTouchEvent(ev)
    }

    override fun onDown(e: MotionEvent?): Boolean {
        return true
    }

    override fun onShowPress(e: MotionEvent?) {
    }

    override fun onSingleTapUp(e: MotionEvent?): Boolean {
        return false
    }

    override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
        scrollBy(distanceX.toInt(), 0)
        return false
    }

    override fun onLongPress(e: MotionEvent?) {
    }

    override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
        if (abs(velocityX) > flingVelocity) {
            //发生惯性
            scroller.abortAnimation()
            val scrollX = this.scrollX
            val scrollY = this.scrollY
            val finalX = if (velocityX > 0) {
                if (scrollX > 0) {
                    0
                } else {
                    -width
                }
            } else {
                if (scrollX > 0) {
                    width
                } else {
                   0
                }
            }
            val finalY = if (velocityY > 0) {
                if (scrollY > 0) {
                    0
                } else {
                    -height
                }
            } else {
                if (scrollX > 0) {
                    height
                } else {
                    0
                }
            }
            scroller.startScroll(scrollX, scrollY, finalX - scrollX, 0)
            invalidate()
        }
        return false
    }

    override fun computeScroll() {
        super.computeScroll()
        if (scroller.computeScrollOffset() && scroller.currX != scroller.finalX) {
            scrollTo(scroller.currX, 0)
            invalidate()
        }
    }
}